package org.redis.cluster.transport.support;

import org.redis.cluster.transport.ByteBuffer;
import org.redis.cluster.transport.protocol.ProtocolDecoder;
import org.redis.cluster.transport.protocol.ProtocolOutput;
import org.redis.cluster.transport.session.Session;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public abstract class AbstractReplayingProtocolDecoder implements ProtocolDecoder {
	
	public final static String POSITION_CONTEXT="_position";
	
	protected final Logger logger=LoggerFactory.getLogger(getClass());
	
	@Override
	public void decode(ByteBuffer buffer, Session session, ProtocolOutput output) {
		ReplayingByteBuffer replayingByteBuffer=new ReplayingByteBuffer(buffer);
		ReplayingProtocolOutput replayingProtocolOutput=new ReplayingProtocolOutput(output);
			
		try {
			doDecode(replayingByteBuffer, session, replayingProtocolOutput);
		}
		catch(ReplayingException e) {
			int position=getPosition(session, replayingByteBuffer);
			if(position!=-1) {
				replayingByteBuffer.position(position);
			}
		}
	}
	
	protected int getPosition(Session session,ByteBuffer buffer) {
		Integer position=session.getContext().get(POSITION_CONTEXT);
		if(position==null) {
			return -1;
		}
		
		return position;
	}
	
	protected boolean checkPosition(Session session,ByteBuffer buffer) {
		return session.getContext().put(POSITION_CONTEXT, buffer.position());
	}

	/**
	 * 解码
	 * @param buffer
	 * @param session
	 * @param output
	 */
	protected abstract void doDecode(ByteBuffer buffer, Session session, ProtocolOutput output);
}